package uns.fit.gis.ui;

import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import javax.microedition.lcdui.TextField;

import uns.fit.gis.MapDrawer;
import uns.fit.gis.Util;
import uns.fit.gis.VietnameseConverter;
import uns.fit.gis.i18n.LocaleManager;
import uns.fit.gis.mapdrawer.LayerConfig;
import uns.fit.gis.mapdrawer.MapCanvas;
import uns.fit.gis.mapobj.SimpleLocation;

public class SearchLocationForm extends Form implements ItemStateListener,
		CommandListener {
	private int choiceIndex = 0;
	private int baseIndex = 0;
	private int x = 0;
	private int y = 0;
	private MapDrawer midlet;
    private String strQuery;
    private String locationName;
    private int nLocations;
    
    private SimpleLocation location;

	private Command backCommand = new Command(LocaleManager.getMessage("back"), Command.BACK, 0);
	private Command selectCommand = new Command(LocaleManager.getMessage("showmap"), Command.ITEM, 1);
	private Command prevCommand = new Command(LocaleManager.getMessage("next"), Command.ITEM, 1);
	private Command nextCommand = new Command(LocaleManager.getMessage("prev"), Command.ITEM, 1);
	private TextField nameCondition = new TextField(LocaleManager.getMessage("name"), "", 20,
			TextField.ANY);
	private ChoiceGroup resultGroup = new ChoiceGroup(LocaleManager.getMessage("result"), ChoiceGroup.EXCLUSIVE);
	
	private int[] choiceGroupLocationIds;
	private int curPlaceIndex = -1;
	public static int selectedLocationId = -1;
	
    private TextField radiusCondition = new TextField(LocaleManager.getMessage("range"), "500", 20,
    			TextField.NUMERIC);
    private ChoiceGroup typeGroup = new ChoiceGroup(LocaleManager.getMessage("locationtype"), ChoiceGroup.MULTIPLE);
        
    private int[] selectedLocationTypes;
        
	public SearchLocationForm(String title, MapDrawer midlet) {
		super(title);

		nameCondition.setInitialInputMode("MIDP_UPPERCASE_LATIN");
		append(nameCondition);
		
		append(radiusCondition);
		
		typeGroup.append(LocaleManager.getMessage("gasstation"), null);
		typeGroup.append(LocaleManager.getMessage("atm"), null);
		typeGroup.append(LocaleManager.getMessage("school"), null);
		typeGroup.append(LocaleManager.getMessage("store"), null);
		typeGroup.append(LocaleManager.getMessage("cafe"), null);
		append(typeGroup);
		
		append(resultGroup);
		addCommand(backCommand);
		addCommand(selectCommand);
		addCommand(prevCommand);
		addCommand(nextCommand);
		this.midlet = midlet;
		setItemStateListener(this);
		setCommandListener(this);
		choiceGroupLocationIds = new int[10];
        nLocations = MapCanvas.locations.length;
		for(int i = 0; i < choiceGroupLocationIds.length; i ++)
			choiceGroupLocationIds[i] = -1;
	}

	public SearchLocationForm(String arg0, Item[] arg1) {
		super(arg0, arg1);
		// TODO Auto-generated constructor stub
	}

	public void itemStateChanged(final Item item) {
		if (item == nameCondition) {
			if(nameCondition.getString().length() > 0) {
				baseIndex = 0;
				updateChoiceGroup();
			}
		}
		else if(item == typeGroup) {
			baseIndex = 0;
			getSelectedLocationTypes();
			for(int i = 0; i < typeGroup.size(); i ++)
				LayerConfig.setVisible(selectedLocationTypes[i], typeGroup.isSelected(i));
			updateChoiceGroup();
		}
		else if(item == radiusCondition) {
			if(radiusCondition.getString().length() > 0) {
				baseIndex = 0;
				updateChoiceGroup();
			}
		}
	}
	
	public void updateCenter() {
		x = MapCanvas.cursorCenterX;
		y = MapCanvas.cursorCenterY;
		updateChoiceGroup();
	}
	
	private void updateChoiceGroup() {
			resultGroup.deleteAll();
			choiceIndex = 0;
            strQuery = VietnameseConverter.toTextNotMarked(nameCondition.getString()).toUpperCase();
            
            int r = 0;
            if(radiusCondition.getString().length() > 0)
            	r = Integer.valueOf(radiusCondition.getString()).intValue();

			for (int i = 0; i < nLocations; i++) {
				location = MapCanvas.locations[i];
				if(Util.contains(selectedLocationTypes, location.getType())) {
					double d = Util.calculateDistancePoint2Point(x, y, location.getX(), location.getY());
					if(d < r) {
						locationName = Util.decodeCharacters(location.getName());
						if (VietnameseConverter.toTextNotMarked(locationName).toUpperCase().indexOf(strQuery) != -1) {
							if(choiceIndex >= baseIndex && choiceIndex < baseIndex + 10) {
								//System.out.println(locationName + " " + d);
								resultGroup.append(locationName, null);
								choiceGroupLocationIds[choiceIndex - baseIndex] = i;
							}
							choiceIndex ++;
						}
					}
				}
			}
		
	}

	public void commandAction(Command c, Displayable d) {
		if (c == backCommand) {
			midlet.showMapCanvas();
		}
		else if(c == selectCommand) {
			if(resultGroup.getSelectedIndex() != -1) {
				curPlaceIndex = resultGroup.getSelectedIndex();
				selectedLocationId = choiceGroupLocationIds[resultGroup.getSelectedIndex()];
				if(selectedLocationId != -1) {
					Util.centerScreen(MapCanvas.locations[selectedLocationId].getX(), MapCanvas.locations[SearchLocationForm.selectedLocationId].getY());
				}
				midlet.showMapCanvas();
			}
		}
		else if(c == prevCommand) {
			if(baseIndex > 9) {
				baseIndex -= 10;
				updateChoiceGroup();
			}
		}
		else if(c == nextCommand) {
			if(resultGroup.size() > 0) {
				baseIndex += 10;
				updateChoiceGroup();
			}
		}
	}

	private void getSelectedLocationTypes() {
		boolean[] flags = new boolean[typeGroup.size()];
		typeGroup.getSelectedFlags(flags);
		selectedLocationTypes = new int[flags.length];
		for(int i = 0; i < flags.length; i ++) {
			if(flags[i]) {
				switch(i){
				case 0:
					selectedLocationTypes[i] = 1;
					break;
				case 1:
					selectedLocationTypes[i] = 2;
					break;
				case 2:
					selectedLocationTypes[i] = 9;
					break;
				case 3:
					selectedLocationTypes[i] = 25;
					break;
				default:
					selectedLocationTypes[i] = 33;
					break;
				}
			}
			else {
				selectedLocationTypes[i] = -1;
			}
		}
	}
	
	public void centerNextPlace() {
		if(curPlaceIndex != -1) {
			curPlaceIndex ++;
			
			if(curPlaceIndex == resultGroup.size()) 
				curPlaceIndex = 0;
			location = MapCanvas.locations[choiceGroupLocationIds[curPlaceIndex]];
			Util.centerScreen(location.getX(), location.getY());
		}
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}
}
